import { controller, action, routeData } from "maishu-node-mvc";
import { Connection } from "typeorm";
import { connection } from "../database";
import { PageDataRecord } from "../entities";
import { errors } from "../errors";
import { currentAppId } from "../common";
import { guid } from "maishu-chitu-service";

const EXISTS = "_exists";

@controller("page-data")
export class PageDataController {
    @action()
    async list(@connection conn: Connection) {
        let items = await conn.getRepository(PageDataRecord).find();
        return items;
    }

    @action()
    async add(@connection conn: Connection, @routeData { item }: { item: PageDataRecord }, @currentAppId appId) {
        if (item == null) throw errors.routeDataFieldNull("item");
        if (item.pageData == null) throw errors.argumentFieldNull("pageData", "item");
        if (item.name == null) throw errors.argumentFieldNull("name", "item");
        if (!appId) throw errors.argumentNull("appId");

        if (!item.id)
            item.id = guid();

        item.applicationId = appId;
        item.createDateTime = new Date(Date.now());
        await conn.getRepository(PageDataRecord).insert(item);
        let obj = { id: item.id, createDateTime: item.createDateTime } as Partial<PageDataRecord>;
        obj[EXISTS] = true;
        return obj;
    }

    @action()
    async update(@connection conn: Connection, @routeData { item }: { item: Partial<PageDataRecord> }, @currentAppId appId) {
        if (item == null) throw errors.routeDataFieldNull("item");
        if (item.pageData == null) throw errors.argumentFieldNull("pageData", "item");
        if (item.id == null) throw errors.argumentFieldNull("id", "item");
        if (!appId) throw errors.argumentNull("appId");

        let obj: Partial<PageDataRecord> = { pageData: item.pageData };
        if (item.name) {
            obj.name = item.name;
        }
        await conn.getRepository(PageDataRecord).update({ id: item.id, applicationId: appId }, obj);
        return {};
    }

    @action()
    async remove(@connection conn: Connection, id: string) {
        if (!id) throw errors.argumentNull("id");
        await conn.getRepository(PageDataRecord).delete(id);
        return {};
    }

    @action()
    async save(@connection conn: Connection, @routeData { item }: { item: PageDataRecord }, @currentAppId appId): Promise<Partial<PageDataRecord>> {
        if (item == null) throw errors.routeDataFieldNull("item");
        if (item[EXISTS]) {
            delete item[EXISTS];
            return this.update(conn, { item }, appId);
        }

        if (item.id)
            return this.update(conn, { item }, appId);

        return this.add(conn, { item }, appId);
    }

    @action()
    async item(@connection conn: Connection, @routeData { name, id }, @currentAppId appId) {
        if (name == null && id == null)
            throw new Error("One of name or id of route data field can not be null.")

        let repository = conn.getRepository(PageDataRecord);
        let item: PageDataRecord;
        if (name != null) {
            item = await repository.findOne({ name, applicationId: appId });
        }
        else
            item = await repository.findOne(id);

        if (item != null)
            item[EXISTS] = true;

        return item;
    }


}